Ext.define('Seq.Ajax', {
    // requires : ['Ext.window.Toast'], 不要打开，写到自己的项目里面
    singleton: true,
    privates: {
        doDrop(records, index, scope, opts) {
            // console.log("drop : ", index, records.length);
            if (index == records.length) {
                opts.afterDrop && Ext.callback(opts.afterDrop, scope, [opts, records]);
                return;
            }

            var record = records[index], options = {
                method: 'DELETE',
                fnSuccess() {
                    record.store.remove(record);
                    scope.doDrop(records, index + 1, scope, opts);
                },
                fnFailure(options, result) {
                    if ((index + 1) < records.length) {
                        Seq.Msg.confirm(Ext.String.format('删除“{0}”时失败：<br/><br/>{1}<br/><br/>是否继续删除下一条记录？', record
                            .getText(), '对象不存在或者有关联信息'), function (buttonId) {
                            if ('yes' === buttonId) {
                                scope.doDrop(records, index + 1, scope, opts);
                            }
                        });
                    } else {
                        Seq.Msg
                            .error(Ext.String.format('删除“{0}”时失败：<br/><br/>{1}', record.getText(), '对象不存在或者有关联信息'));
                    }
                }
            };
            opts.beforeDrop && opts.beforeDrop(record);

            if (record.data.ignore_id_valid || Ext.isNumeric(record.data.id) || Seq.Ajax.isUuid(record.data.id)) {
                Ext.apply(options, {
                    url: record.store.crul + '/' + record.data.id
                })
            } else {
                Ext.apply(options, {
                    url: record.store.crul,
                    jsonData: Ext.encode(record.data.id)
                })
            }

            scope.request(options);
        }
    },

    toast(content, title) {
        if (Ext.isEmpty(content) || !Ext.isString(content)) {
            content = '操作请求成功';
        }
        Ext.toast({
            html: content,
            title: title,
            closable: false,
            align: 'br',
            slideInDuration: 300,
            minWidth: 200
        });
    },

    request(options) {
        let me = this;
        options.mask && options.mask.mask && !options.mask.getMaskTarget() && options.mask.el
        && options.mask.mask("正在处理，请稍候...");
        Ext.applyIf(options, {
            method: 'GET',
            timeout: 90000,
            fnFailure: me.onFailure,
            callback: me.onReturn
        });
        options.headers = options.headers || {};
        if (Ext.Array.contains(['GET', 'PUT'], options.method)) {
            Ext.apply(options.headers, {
                Accept: 'application/json',
                'Content-Type': 'application/json;charset=UTF-8'
            });
        }
        Ext.Ajax.request(options);
    },

    drop(records, options) {
        var me = this;
        if (0 < records.length) {
            var tip = 1 < records.length ? Ext.String.format('你确认要删除选中的"{0}"条记录吗？', records.length) : Ext.String
                .format('您确认要删除"{0}"吗？', records[0].getText());
            Seq.Msg.confirm(tip, function (buttonId) {
                if ('yes' === buttonId) {
                    me.doDrop(records, 0, me, options);
                }
            });
        }
    },

    deleteInBatch(store, records, options) {
        if (0 < records.length) {
            Seq.Msg.confirm(Ext.String.format('你确认要删除选中的"{0}"条记录吗？', records.length), function (buttonId) {
                if ('yes' === buttonId) {
                    Seq.Ajax.request(Ext.apply({
                        method: 'DELETE',
                        url: store.crul,
                        jsonData: Ext.encode(records)
                    }, options));
                }
            });
        } else {
            options.fnSuccess && Ext.callback(options.fnSuccess);
        }
    },

    isUuid(value) {
        return /^[a-zA-Z0-9]{8}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{12}$/.test(value);
    },

    formValid(forms) {
        var form, len = forms.length;
        for (var i = 0; i < len; i++) {
            form = forms[i];
            if (form.enforceValid) {
                return form.isValid();
            }
        }
        return true;
    },

    markForm(forms, violations) {
        forms.forEach(function (form) {
            form.getForm && form.getForm().markInvalid(violations)
        });
    },

    valueOfForm(forms) {
        var result = {};
        Ext.Array.each(forms, function (form) {
            Ext.apply(result, form.getValues());
        });
        return result;
    },

    submit(forms, options, record, ignoreId) {
        var me = this;
        if (!Ext.isArray(forms)) {
            forms = [forms];
        }
        if (!me.formValid(forms))
            return;
        var data = Ext.isEmpty(record) ? me.valueOfForm(forms) : record.isModel ? record.getData() : record;
        options.params && Ext.apply(data, options.params);
        if (Ext.isEmpty(options.url)) { // 记录提交时，URL直接从store的api中获取
            options.url = record.store.crul
        }
        if (!data.ignore_id_valid) { // 特殊处理，字符串ID
            if (!(Ext.isNumeric(data.id) || Ext.isObject(data.id) || Seq.Ajax.isUuid(data.id))) { // 新建的记录
                delete data.id;
            }
        }
        options.params = record ? Ext.encode(data) : data;
        Ext.applyIf(options, {
            method: 'PUT',
            scope: me,
            forms: forms
        });
        this.request(options);
    },

    onFailure(options, result, status) {
        var view = Ext.getApplication().getMainView(), ctrl = view.getController(), vm = view.getViewModel();
        switch (status) {
            case 200 : // 服务端业务逻辑错误
                if (options.forms) {
                    if (result.violations) { // 分项提示
                        return Seq.Ajax.markForm(options.forms, result.violations);
                    }
                }
                if (result.message) {
                    Seq.Msg.error('服务器错误：<br/><br/>' + result.message);
                }
                break;
            case 401 : // 未登录
                if (vm.get('user')) { // 已经登录过
                    window.location.replace(window.location.origin + window.location.pathname);
                } else { // 未登录过
                    ctrl.fireEvent('redirect', '#login', {});
                }
                break;
            case 403 :
                Seq.Msg.error('你没有执行该操作的权限，请联系系统管理员赋予相应角色。');
                break;
            case 404 : // 请求失败
            case 405 : // 不允许的方法
                ctrl.redirectTo('error404window');
                break;
            case 500 : // 请求失败
                if (result.message) {
                    Seq.Msg.error('服务器内部错误：<br/><br/>' + result.message);
                } else {
                    ctrl.redirectTo('error500window');
                }
                break;
            default : //
                ctrl.redirectTo('blankpage');
        }
    },

    onReturn(opt, success, response) {
        // console.log("response : ", response);
        opt.mask && opt.mask.unmask && opt.mask.unmask();

        var result = {
            success: true
        }
        var json = Ext.decode(response.responseText, true);
        if (json) {
            result = json;
        } else {
            result.data = response.responseText;
        }

        switch (response.status) {
            case 200 :
            case 204 :
                if (!success || false === result.success) {
                    opt.fnFailure && Ext.callback(opt.fnFailure, opt.scope, [opt, result, response.status]);
                } else {
                    if (('POST' == opt.method) && opt.mask) {
                        Seq.Ajax.toast(result.data);
                    }
                    opt.fnSuccess && Ext.callback(opt.fnSuccess, opt.scope, [opt, result]);
                }
                break;
            default :
                if (!Ext.isDefined(result.success)) {
                    result.success = false;
                }
                opt.fnFailure && Ext.callback(opt.fnFailure, opt.scope, [opt, result, response.status]);
        }
    }
});